- Published on
[大厂实践] Twitter 客户端负载均衡实践
- Authors
- Name
- 俞凡
本文介绍了 Twitter 在客户端负载均衡技术方面的实践,以牺牲中心化控制为代价,构建更高性能的负载均衡系统。原文:Client-Side Load Balancing: Concepts, Benefits & Practical Uses
当我们运行数千后端服务时,即使路由上的一个小延迟也会减慢所有服务的速度。客户端负载均衡将路由决策从中间层转移到客户端,从而减少开销并提高了速度。Twitter 就采用了这种模式,从而满足业务需求,避免路由瓶颈。我们来看看这种模式是如何工作的,以及为什么重要。
什么是客户端负载均衡?
传统负载均衡依赖于中央路由器,这个中间层会接收每一个客户端请求,并将其转发到后端服务器。路由器是整个路径中的关键部分。
客户端负载均衡消除了这一额外传输环节。每个客户端都会收到一份可用后端服务器列表,将这份列表存储在本地,并据此决定将请求发送至何处。这使得路由过程更快、更可靠,也更易于扩展。
不再是由一台路由器独自承担所有工作,而是每个客户端都分担相应的任务。
客户端负载均衡的优势
- 降低延时
请求直接从客户端发送至服务器,无需经过中央路由器,从而避免因路由器而产生的延迟问题。
- 无单点故障
如果某个客户端出现问题,其他客户端仍能继续正常工作。整个系统不存在可能导致整体崩溃情况的单一关键节点。
- 更优的流量分配
每个客户端都会自行分配流量,将负载均匀分配到所有服务器上。
- 本地控制
客户端会根据实时反馈做出路由决策,可以迅速重试,也可以在必要时暂停操作。
- 易于扩展
随着服务增多,添加新的客户端或服务器并不会使中央路由器不堪重负,该系统能够自然的进行扩展。
Twitter 如何使用客户端负载均衡
Twitter 使用名为 Finagle 的库来管理服务之间的通信。此外还构建了名为 Aperture 的客户端负载均衡器。该系统能够处理跨数千微服务的请求路由。
Aperture 利用一组虚拟服务器,为每个客户端分配一小块区域。这种方法有助于 Twitter 保持请求路由的快速且公平性。随着时间推移,Twitter 对四种不同的 Aperture 系统进行了试验。
Aperture 类型
| 类型 | 描述 |
|---|---|
| Mesh topology 网状拓扑 | 客户端与所有服务器建立连接。适用于小规模部署,但无法横向扩展。 |
| Random aperture 随机孔径 | 每个客户端随机挑选一部分服务器。实现简单,但可能导致负载不均。 |
| Deterministic-Discrete ring 确定性离散环 | 服务器被划分为固定槽位,每个客户端通过哈希获得一个稳定的窗口。高效。 |
| Deterministic-Continuous ring 确定性连续环 | 服务器在哈希空间中连续映射,窗口可动态调整。灵活,但实现更复杂。 |
- Mesh topology(网状拓扑)
在网状架构中,每个客户端都与每个服务器建立连接。这种方式能提供最大的可见性,但连接成本很高。
- 在小型系统中运行良好
- 但在大型集群中无法扩展
- 存在过多的开放连接和过高的内存使用量
Twitter 很早就摒弃了这种设计。
- **Random aperture(随机孔径)
每个客户端都会随机连接到后端服务器的一组子集。
- 易于实施
- 减少连接数量
- 但随机性可能会导致不均衡。一些客户端可能会连接到较慢的服务器。
- 确定性孔径 —— 离散环结构
这是 Twitter 最常用的方法。服务器以固定的环形排列方式布置,每个服务器根据一致性哈希获得固定位置。
- 客户端获得固定大小的窗口(即 aperture),进入环形区域
- 窗口基于客户端 ID 设定,因此是稳定的
- 请求会被均匀且可预测的分发
如果需要,窗口大小可根据流量情况进行扩大或缩小,从而在不使服务器过载的情况下更易于管理负载。
- 确定性孔径 —— 连续环结构
此版本采用连续哈希空间(类似于从 0 到 1 的一个圆环)。服务器根据权重或容量被映射到该空间中。
- 客户端从哈希环中选择分段
- 适用于服务器负载变化的情况
- 更具灵活性,但稍微复杂一些
无论是离散环还是连续环,都能提供强大的控制功能,能帮助 Twitter 在数百万次请求中管理延迟和公平性。
实际运作方式
客户端会记录每次请求所花费的时间。如果延迟增加或队列变长,就会扩大窗口大小,连接更多服务器。如果流量减少,就会缩小窗口大小。
在该窗口(Aperture)内,Twitter 采用二进制幂次选择(P2C)的方式来选定服务器:
- 从该窗口中随机选取两个服务器
- 将请求发送至当前待处理请求较少的那个服务器
这种方法简单却有效,能够避免热点问题,并保证响应时间。
另一个用例:Lyft 的 Envoy
Lyft 采用 Envoy(一款开源边缘和服务代理工具),运行在每个服务内部,并负责处理客户端的路由。
与 Twitter 类似,Envoy 也从服务发现工具中获取到一组可用后端服务器列表,决定将流量发送至何处,重试失败的请求,并在本地记录指标数据。
这使得 Lyft 能够对流量进行精细控制,同时又能避免路由器过载。该架构有助于 Lyft 在数千个容器之间实现扩展。
客户端负载均衡的缺点
- 服务器列表过时:如果后端服务器崩溃,某些客户端可能不会立即察觉。
- 客户端复杂度增加:客户端必须处理路由逻辑、重试和延迟策略,增加了代码量和责任。
- 全局意识降低:每个客户端只能看到系统部分区域,可能会错过更广泛的趋势,比如全球负载分布不均。
- 内存使用量更高(在某些设计中):网状结构或大型窗口可能需要打开大量连接。
总结
客户端负载均衡以集中控制为代价换取速度和灵活性。Twitter 的 Aperture 系统使用智能算法和稳定的环形结构实现低延迟路由流量。其他公司,如 Lyft,也采用了类似设计。虽然这种方法增加了客户端复杂性,但消除了中心化瓶颈,在大规模应用中会产生巨大影响。